//Lindsay Ergenekan 
//ergenekl@onid.oregonstate.edu 
//CS311 - 400
//Homework 5 - Uniqify  


#include "hw5.h"

#define MAXBYTES = 50;

int main(int argc, char *argv[])
{

    char c;
    int n; 
 //   int pfd[2];
    int i; //counter into
    int j;//counter int
   const char delimiter[] = " \n!\"#$%,.?][-+_\\/<>=@^:;&\'-')(*1234567890";
    char s1 [200];
    char * token; //variable to record the tokens
    int count; //variable to record the number of words
    void *root = NULL; //pointer to the root of the bst
    struct word_t *ret = malloc(sizeof(word_t)); //word_t structure - catches the return value of the tsearch to update
    word_t *val; //value
    char * ptr; //pointer to help use the tokens
 //   char * token_array[10000];
    key_t testKey; //variable test key
    struct messsage_struct *message_t = malloc(sizeof(message_struct));
    struct message_struct msg; //variable message send buffer
    int received_bytes; 
    struct message_struct rcv; //variable message receive buffer
    int msgqid; //variable to record the msg qid
    int * message_array; //variable to hold the message IDs

    while ((c = getopt(argc, argv, "n:")) != -1)
    switch (c){ 
        case 'n':
            n = atoi(argv[2]);
            if (n >= 50){
                printf("Too large a number.");
                exit(1);
            }
   //         else { 
   //          printf("%d \n", n);
    //        }
        }

//create the test key
testKey = ftok(__FILE__, 's');

message_array = malloc(sizeof(n));

for (i = 0; i < n; ++i)
{
    message_array[i] = msgget(testKey+i, 0666 | IPC_CREAT); // creates message queue to post and pull from
    printf(" %d Processes:  %d \n", i, message_array[i]);
}

//msgqid = message_array[1];

received_bytes = 0; //set the received variable to 0
//printf ("received bytes at 0 : %d \n", received_bytes);

for (i =0; i < n; ++i)
{ 
  switch (fork()) {

    case -1:
       printf("fork issue \n");
       exit(1);
    case 0:   
    for (;;)
    {
        received_bytes = msgrcv(message_array[i], &rcv, sizeof(rcv.mtext), 0, MSG_NOERROR);  
//        printf(" msgrcv bytes = %d \n", received_bytes); 
//        printf("message type: %d \n", rcv.mtype);

        //   printf ("received bytes after msgrcvd %d \n", received_bytes);
        if(received_bytes == -1)
            {printf(" EXIT [%d] \n", message_array[i]);
            exit(2);}
        else if (rcv.mtype == 7)
            {printf("exiting\n");
//walk through the tree
            twalk(root, walker);
            exit(1);}
        else
            {
        //  printf(" child [%d] received type %d \n", msgqid, rcv.mtype);
            printf(" child [%d] : %s  \n", message_array[i], rcv.mtext);
            val = calloc(1, sizeof(word_t));
            val->word = strdup(rcv.mtext);
            ret = tsearch(message_struct, &root, cmp);
        //incriment the number of the item
           (*(word_t **)ret)->number += 1;

            } 

    }
    default:           
        break;
  }
}

count = 0; //set variable to count the number of words to 0
i = 0; //set i to 0
 j=0; //set j to 0
while (fgets(s1, 200, stdin))
{
    ptr = s1;
//this while loop allows individual tokens to be handled
    while ((token =strtok(ptr, delimiter)) != NULL)
        {
///////////////////////////////////THiS IS WHERE I HANDLE INDIVIDUAL TOKENS!!!!!!!!!!!!!
        ++count; 
//reset the ptr
        ptr = NULL;

//make all lower case
        for (i =0; i < strlen(token); ++i)
                {token[i] = tolower(token[i]);}
//put the value in the message_struct
        message_struct.mtype = 1;
        strcpy(message_struct.mtext, token);

        received_bytes =0; 
//print what was put into the message_struct
//       printf(" %d %s \n", message_struct.mtype, message_struct.mtext);

        received_bytes = msgsnd(message_array[j%n], &message_struct, sizeof(message_struct.mtext), MSG_NOERROR);
 
        ++j; 

       }//
 //   printf("finished fgets while loop");
    }

message_struct.mtype = 7; 

for (i = 0; i < n; ++i)
{
    received_bytes = msgsnd(message_array[i], &message_struct, sizeof(message_struct.mtext), MSG_NOERROR);
}

for (i = 0; i < n; ++i)
{
    if (wait(NULL) == -1)
        { printf("wait %d did not work\n", i);}
    else 
        {printf("wait found child\n");}
}

for (i = 0; i < n; ++i)
{
    msgctl(message_array[i], IPC_RMID, NULL); // remove the queue
}

for (i = 0; i < n; ++i)
{
    kill(message_array[i],SIGTERM);//kill the child process
}


//walk through the tree
 //   twalk(root, walker);


return 0; 
}

int cmp(const void *a, const void *b)
{
    word_t *fa, *fb;
    fa = (word_t*)a;
    fb = (word_t*)b;

    return strcmp(fa->word, fb->word);
}

void walker(const void *node, const VISIT which, const int depth)
{
    printf("in walker");
    if(which == 1 || which == 3)
    {
        word_t *f;
        f = *(word_t **)node;
        printf("      %d %s\n", f->number, f->word);
    }
/*  else if(which == "leaf")
    {
        foo_t *f;
        f = *(foo_t **)node;
        printf("\nWord is:%s\nCount is: %d\n", f->word, f->count);
    }
*/
}

/*
 add_BST(  )
{
 //       val = calloc(1, sizeof(word_t));
 //       val->word = strdup(token);
 //       ret = tsearch(message_struct, &root, cmp);
        //incriment the number of the item
 //        (*(word_t **)ret)->number += 1;

return root; 
}
*/